package com.shenhan.readwritelock;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.IntStream;

/**
 * @author shenhan
 * @create 2020/6/11 11:49
 * @description
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();
        IntStream.range(1, 6).forEach(i -> new Thread(() -> myCache.put(String.valueOf(i), i + "test"),
                String.valueOf(i)).start());
        IntStream.range(1, 6).forEach(i -> new Thread(() -> myCache.get(String.valueOf(i)),
                String.valueOf(i)).start());
    }
}

/**
 * 加锁后的自定义缓存
 */
class MyCacheLock {
    private final Map<String, Object> map = new HashMap<>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    public void put(String k, Object v) {
        lock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + " 写入" + k);
            map.put(k, v);
            System.out.println(Thread.currentThread().getName() + " 写入成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }

    public void get(String k) {
        lock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + " 读取 " + k);
            final Object o = map.get(k);
            System.out.println(Thread.currentThread().getName() + " 读取成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
    }
}

/**
 * 自定义缓存
 */
class MyCache {
    private volatile Map<String, Object> map = new HashMap<>();

    public void put(String k, Object v) {
        System.out.println(Thread.currentThread().getName() + " 写入" + k);
        map.put(k, v);
        System.out.println(Thread.currentThread().getName() + " 写入成功");
    }

    public void get(String k) {
        System.out.println(Thread.currentThread().getName() + " 读取 " + k);
        final Object o = map.get(k);
        System.out.println(Thread.currentThread().getName() + " 读取成功");
    }
}
